import os
import subprocess
import sys
import ConfigParser as cp

def get_config_files():	
	config_files = []
	for s in [os.path.expanduser('~'), os.path.expandvars('$WINDIR'), \
			os.path.expandvars('$HOME'), os.path.curdir, \
			os.path.dirname(sys.argv[0])]:
			s = os.path.join(s, '.ts_env')
			if os.path.isfile(s):
				config_files.append(s)
	return config_files

class EnvManager(object):
	def __init__(self):
		config_files = get_config_files()
		assert config_files, 'No configuration files found'

		self.__parser = cp.SafeConfigParser()
		self.__parser.read(config_files)

		self.__env_stack = []

	def get_element_separator(self):
		if os.name == 'posix':
			return ':'
		else:
			return ';'

	def get_config_element_separator(self):
		if sys.platform == 'cygwin':
			return ';'
		return self.get_element_separator()

	def get_value_filtered(self, value):
		#value = os.path.expandvars(value)
		if sys.platform == 'cygwin':
			l = value.split(self.get_config_element_separator())
			r = []
			for s in l:
				s = s.strip()
				if s:
					s = subprocess.Popen(['cygpath', s], \
						stdout=subprocess.PIPE).communicate()[0].strip()
					r.append(s)
			value = self.get_element_separator().join(r)
		return value

	def __apply_env(self, environ, is_merged, is_appended):
		for k in environ:
			v = ''
			try:
				if is_merged:
					if is_appended:
						v = os.environ[k] + self.get_element_separator() \
							+ environ[k]
					else:
						v = environ[k] + self.get_element_separator() \
							+ os.environ[k]
				else:
					v = environ[k]
			except:
				v = environ[k]
			os.environ[k] = v
		return

	def get_env_list(self):
		return self.__parser.sections()

	def get_env(self, id):
		e = {}
		for k in self.__parser.options(id):
			k = k.upper()
			v = self.__parser.get(id, k)
			v = self.get_value_filtered(v)
			e[k] = v
		return e

	def __get_current_env_copy(self):
		e = {}
		for k in os.environ:
			e[k] = os.environ[k]
		return e

	def push(self, section, is_merged = False, is_appended = False):
		assert self.__parser.has_section(section), \
			'No environment "%s" defined' % section
		self.__env_stack.append(self.__get_current_env_copy())
		self.__apply_env(self.get_env(section), is_merged, \
			is_appended)
		return

	def pop(self):
		assert self.__env_stack, 'No environments in stack to pop'
		os.environ = {}
		self.__apply_env(self.__env_stack.pop(), False, False)
		return

def main(argv):
	m = EnvManager()
	l = m.get_env_list()
	print '\n'.join(l)

	if ('-t' in argv) and (len(l) > 1):
		if '-d' in argv:
			import pdb
			pdb.set_trace()
		print 'PATH before test:\n%s' % os.environ['PATH']
		print '================================================================================'
		m.push(l[0], True)
		print 'PATH after first push with merge:\n%s' % os.environ['PATH']
		print '================================================================================'
		m.push(l[1])
		print 'PATH after second push without merge:\n%s' % os.environ['PATH']
		print '================================================================================'
		m.pop()
		m.pop()
		print 'PATH after test:\n%s' % os.environ['PATH']

if __name__ == '__main__':
	main(sys.argv[1:])

